package com.tmsps.ne4weixin.utils;

import java.io.StringReader;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import com.tmsps.ne4weixin.config.WxConfig;
import com.tmsps.ne4weixin.encrypt.AesException;
import com.tmsps.ne4weixin.encrypt.WXBizMsgCrypt;

/**
 * @author zhangwei 396033084@qq.com MsgEncryptUtil
 */
public class MsgEncryptUtil {
	protected static Logger log = LoggerFactory.getLogger(MsgEncryptUtil.class);

	private static final String format = "<xml><ToUserName><![CDATA[toUser]]></ToUserName><Encrypt><![CDATA[%1$s]]></Encrypt></xml>";

	public static String encrypt(String msg, String timestamp, String nonce, WxConfig wc) {
		try {
			WXBizMsgCrypt pc = new WXBizMsgCrypt(wc.getToken(), wc.getEncodingaeskey(), wc.getAppid());
			return pc.encryptMsg(msg, timestamp, nonce);
		} catch (AesException e) {
			log.error("weixin encrypt msg err :", e);
			throw new RuntimeException(e);
		}
	}

	public static String decrypt(String ciphertext, String timestamp, String nonce, String msgSignature, WxConfig wc) {
		try {
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			StringReader sr = new StringReader(ciphertext);
			InputSource is = new InputSource(sr);
			Document document = db.parse(is);

			Element root = document.getDocumentElement();
			NodeList nodelist1 = root.getElementsByTagName("Encrypt");
			String encrypt = nodelist1.item(0).getTextContent();
			String fromXML = String.format(format, encrypt);

			String encodingAesKey = wc.getEncodingaeskey();
			if (encodingAesKey == null) {
				log.error("encodingAesKey can not be null !!!");
				throw new IllegalStateException("encodingAesKey can not be null !!!");
			}
			WXBizMsgCrypt pc = new WXBizMsgCrypt(wc.getToken(), encodingAesKey, wc.getAppid());
			return pc.decryptMsg(msgSignature, timestamp, nonce, fromXML);
		} catch (Exception e) {
			log.error("weixin decrypt msg err :", e);
			throw new RuntimeException(e);
		}
	}
}
